/****************************************************************************************
 *
 * 本文件只放区块链请求方法、接口方法，相关数据处理方法，不放纯工具方法
 * 本文件只放区块链请求方法、接口方法，相关数据处理方法，不放纯工具方法
 * 本文件只放区块链请求方法、接口方法，相关数据处理方法，不放纯工具方法
 *
 * *************************************************************************************/

//资源
import { get } from '@/axios/http'
import { hex2Num, trigerSmartContract } from "@/libs/tron.lib";
import { getEffectiveValue, precisionToNum } from "@/libs/site.utils";
import { MANAGE_BASEURL, MOCK, voteGovernanceContract } from "@/views/manage/js/manage.lib";
import { Message } from "element-ui";

///////////////////////////////////////////////////   以下是区块链方法  ////////////////////////////////////////////////////////////
///////////////////////////////////////////////////   以下是区块链方法  ////////////////////////////////////////////////////////////
///////////////////////////////////////////////////   以下是区块链方法  ////////////////////////////////////////////////////////////

/**
 * 用户投票操作（票数，赞成还是反对）
 * @param pool
 * @param proposalId 区块链上的投票自增id
 * @param sender 用户
 * @param amount 投票数量
 * @param support 支持或反对
 * @param callback
 * @param confirmCallback
 */
export function tronUserVoteSubmit(proposalId, sender, amount, support, callback, confirmCallback) {
	let func = "castVoteDeposit(uint256,uint256,bool)";
	let parameters = [{
		type: 'uint',
		value: proposalId
	}, {
		type: 'uint',
		value: amount
	}, {
		type: 'bool',
		value: support
	}];
	trigerSmartContract(voteGovernanceContract, func, parameters, sender, callback, confirmCallback);
}

/**
 * 对复审结果复核（实际上逻辑做成与投票形式一样的）
 * @param proposalId 投票的id
 * @param amount 数量
 * @param support 支持或反对
 * @param sender
 * @param callback
 * @param confirmCallback
 */
export function tronAdminContestResultCheck(proposalId, amount, support, sender, callback, confirmCallback) {
	let func = "adminVoteDeposit(uint256,uint256,bool)";
	let parameters = [{
		type: 'uint',
		value: proposalId
	}, {
		type: 'uint',
		value: amount
	}, {
		type: 'bool',
		value: support
	}];
	console.log(parameters)
	trigerSmartContract(voteGovernanceContract, func, parameters, sender, callback, confirmCallback);
}


///////////////////////////////////////////////////   以下是异步api  ////////////////////////////////////////////////////////////
///////////////////////////////////////////////////   以下是异步api  ////////////////////////////////////////////////////////////
///////////////////////////////////////////////////   以下是异步api  ////////////////////////////////////////////////////////////


/**
 * 获取投票列表数据，排序是赞成票多的排前面
 * @param param
 * @param callback
 */
export const apiManageList = function (param, callback) {
	let _prefix = !MOCK ? '/VotingPreEntryServlet?act=' : ''
	// return axiosQuery(MANAGE_BASEURL +_prefix + 'ManageList', param, 'GET', callback)
	get(MANAGE_BASEURL + _prefix + 'ManageList',param).then((res)=>{
		callback(res)
	})
}
// todo 合并为1个接口
/**
 * 获取我的发起投票数量
 * @param param
 * @param callback
 */
export const apiMyVoteCount = function (param, callback) {
	let _prefix = !MOCK ? '/VotingPreEntryServlet?act=' : ''
	// return axiosQuery(MANAGE_BASEURL + _prefix + 'MyVoteCreatedCount', param, 'GET',callback)
	get(MANAGE_BASEURL + _prefix + 'MyVoteCount',param).then((res)=>{
		callback(res)
	})
}

///////////////////////////////////////////////////   以下是工具方法  ////////////////////////////////////////////////////////////
///////////////////////////////////////////////////   以下是工具方法  ////////////////////////////////////////////////////////////
///////////////////////////////////////////////////   以下是工具方法  ////////////////////////////////////////////////////////////

/**
 * 解析从区块链请求到的投票的实时数据，返回对应投票列表顺序的数组
 * 每个位置的数据是什么作用，详见映射配置：DATAMAP_VOTE
 * 目前区块链方法返回的数据，是多个投票的数据都一起返回，输出的平级数据，并非数组
 * 前3位不管，第4位为渲染用到的实际投票数据的长度，第5位开始到结束为实际有效数据
 * 假设要拉取的投票有2个，区块链方法每个投票输出的数据是5个，那就有2*5=10个有效数据
 * 再加上前面的4位非渲染数据，则有14位数据
 * @param param 数据内容
 * @param groupLength 每X个属于一个投票
 * @returns {any}
 */
export const getEffectiveValueForVote = function(param, groupLength){
	let _effectiveIndex = 4 //有效数据的长度值的索引位置
	let _effectiveLength = hex2Num(getEffectiveValue(param, _effectiveIndex, 64),0); // //解析出后面要用的数据的长度
	// console.log('》》》》》》》》》》》》》》》》》》》》》》》数据包装方法：解析结果:',_effectiveLength)
	let effectiveArr = []
	//根据长度来循环取出数据
	for(
		let i = 1 ;
		i < _effectiveLength+1;
		i++
	){
		let _temp = hex2Num(getEffectiveValue(param, _effectiveIndex + i, 64),0)
		effectiveArr.push(_temp)
		// console.log('》》》》》》》》》》》》》》》》》》》》》》》数据包装方法：解析遍历数据:',i,':',_temp)
	}
	//把一维数组处理，按数量，成每X个的二维数据，对投票应列表数据
	let unFlat = Array(_effectiveLength/groupLength).fill('').reduce((ret,cur,index)=>{
		let child = effectiveArr.slice(groupLength*index,groupLength*(index+1))
		ret.push(child)
		return ret
	},[])

	return unFlat
}


//todo 这里是处理3个结果的，要改掉
/**
 * 解析区块链返回的赛事数据（splice）
 * @param param 区块链返回的数据
 * @returns {[]}
 */
export const getEffectiveValueForContest2 = function(param){
	let flatArr = [] //扁平化数组
	let unFlat = [] //非扁平，用于返回
	let groupLength = param.length/64 //算出共有几个数据
	//遍历解析，放到一个数组中
	for(let i = 0;i<groupLength;i++) {
		let _analyzing = hex2Num(getEffectiveValue(param, i+1, 64),0)
		flatArr.push(_analyzing)
	}
	console.log('********************************全部解析结果：',flatArr)

	let _arrLength = 0;//下面要用到的数组长度

	unFlat[1] = flatArr.splice(0,1).join('');//状态
	flatArr.splice(0,4);//删掉后面4个数组参数的指针位置
	flatArr.splice(0,1);//删掉赛事结果（前端不用这个）
	//处理odds
	unFlat[2] = flatArr.splice(0,3).map(item=>item/1000)
	return unFlat
}

/**
 * 解析出所有数据，按顺序存放
 * @param param
 * @param skip 区块链返回的数据如果是数组，要跳过前面2位的数据(数组长度，指针位置？)，第三位开始才是要的数据
 * @returns {*[]}
 */
export const getEffectiveValueForContest3 = function(param, skip = 0 ) {
	let flatArr = [] //扁平化数组
	let groupLength = param.length / 64 //算出共有几个数据
	//遍历解析，放到一个数组中
	for (let i = 0; i < groupLength; i++) {
		let _analyzing = hex2Num(getEffectiveValue(param, i + 1, 64), 0)
		flatArr.push(_analyzing)
	}
	return flatArr.slice(skip);
}


/**
 * 对投票列表数据进行包装处理，比如精度转换
 * 注意这里面操作了特定的属性，目前用在投票中心列表，是否能用在其它地方不知道
 * @param data
 * @returns {*}
 */
export const voteDatalistWrapProcessing = function (data){
	return data.map((item)=> {
		item.forVotes     = precisionToNum(item.forVotes)//处理投票达成阈值精度
		item.againstVotes = precisionToNum(item.againstVotes)//处理投票达成阈值精度
		item.quorumVotes  = precisionToNum(item.quorumVotes)//处理投票达成阈值精度
		return item
	})
}

/**
 * 验证分数，本页面使用
 * @param score 分数
 * @param rule 规则：zero验证0，less验证小于1,dot验证小数
 * @returns {{}}
 */
export function validateScore (score, rule = [], msgFixed = '') {
	let _boolean = true //默认验证通过
	score        = +score //强制转为数字
	
	//是否填写
	//if (score == undefined || score == "") {
	if (score == undefined) {
		_boolean = false
		Message.error('请填写' + msgFixed)
		return _boolean
	}
	
	//验证是否有小数(当然，这个规则同时不能小于1)
	if (rule.includes('dot')) {
		if (/\./.test(score)) {
			_boolean = false
			Message.error(msgFixed + '不能有小数，当前是:' + score)
			return _boolean
		}
	}
	
	//验证是否为零
	if (rule.includes('zero')) {
		if (score == 0) {
			_boolean = false
			Message.error(msgFixed + '不能等于0，当前是:' + score)
			return _boolean
		}
	}
	//验证是否为零
	if (rule.includes('less')) {
		if (score < 1) {
			_boolean = false
			Message.error(msgFixed + '不能小于1，当前是:' + score)
			return _boolean
		}
	}
	
	return _boolean
	
}
